#include "mat_game_editor.h"
#include "mat_game.h"
#include "mat_define.h"
#include "mat_gem.h"
#include "mat_gamerule.h"

#include "editor/editor_brush.h"
#include "application/game_script.h"
#include "math/spline2d.h"
#include "math/facing.h"
#include "math/interpolation.h"
#include "console/console.h"
#include "ui/ui_manager.h"
#include "gameflow/game_flow_manager.h"
#include "dd/dd_man.h"
#include "font/font_manager.h"
#include "script/scripthelper.h"
#include "font/font_manager.h"
#include "input/keyboard.h"
#include "graphics/graphics_util.h"

#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging
#include "util/timer.h"		    // logging


#include <algorithm>
#include <cassert>
using namespace script;


//////////////////////////////////////////////////////////
/// Tile objects
class MATBrushTile : public EditorBrush
{
public:
	MATBrushTile(MATGameEditor* pEditor) :
		EditorBrush(pEditor),
		m_Type(TILE_HARD)
	{		
		m_HelpText = " LMB to Place, \n RMB to delete, \n MWheel To change Type";		
		
	};
	
	virtual void			CreateObj()
	{
		m_Type = TILE_HARD;
	};

	virtual void	Render(const math::Vec2& Offset, float Scale)
	{
		if(m_Type > 0 && m_Type < TILE_COUNT)
		{
			if(m_Type == TILE_UNMOVEABLEGEM2)
			{	
				ui::UISprite* pSprite2 = ((MATGame*)GetGame())->GetTileSprite(TILE_HARD);
				pSprite2->m_Pos = m_pEditor->GetMousePos();
				pSprite2->RenderRotated();
				
			}

			ui::UISprite* pSprite = ((MATGame*)GetGame())->GetTileSprite(m_Type);
			pSprite->m_Pos = m_pEditor->GetMousePos();
			pSprite->RenderRotated();
			FontManager::Instance().PrintCentered(m_pEditor->GetMousePos(), "%i",  m_Type);
		}
	};

	// Rotating is changing type
	virtual void	Rotate(int Dir)
	{
		m_Type =  TILE_TYPE((int)m_Type + 1);
		if ( m_Type >= TILE_COUNT)
			m_Type = TILE_HARD;
	};

	virtual void	PressLMB()
	{
		int x = 0, y = 0;
		math::Vec2 P = m_pEditor->GetMousePos();
		((MATGame*)GetGame())->GetBoardXY(P,x,y);
		if(x >= 0 && y >= 0)
			MATLogicBoard::Instance().ChangeTile(y,x, m_Type);
	};
	
	virtual bool	TryDelete(const math::Vec2& P) 
	{ 
		int x = 0, y = 0;
		((MATGame*)GetGame())->GetBoardXY(P,x,y);
		if(x >= 0 && y >= 0)
		{
			MATLogicBoard::Instance().ChangeTile(y,x, TILE_NORMAL);
			return true;			
		}
		return false;
	};	

	TILE_TYPE		m_Type;
	
};

class MATBrushBomb : public EditorBrush
{
public:
	MATBrushBomb(MATGameEditor* pEditor) :
		EditorBrush(pEditor),	
		m_pGem(NULL)
	{		
		m_HelpText = " LMB to Place, \n RMB to delete, \n MWheel To change Type";	
		
		CreateObj();
	};

	virtual ~MATBrushBomb() 
	{
		m_pGem->m_IsFinish = true;
	};

	virtual void			CreateObj()
	{
		if(!m_pGem || m_pGem->m_IsFinish)
		{
			m_pGem = MATGameRule::Instance().GetNewGemToSpawn();
			m_pGem->m_IsBomb = true;
			m_pGem->m_IsSmall = false;
			m_pGem->m_Type = 1;
			m_pGem->m_BombTurnToExplode = 21;

		}
	};
	
	virtual void	Render(const math::Vec2& Offset, float Scale)
	{
		if(m_pGem)
		{			
			ui::UISprite* pSprite = ((MATGame*)GetGame())->GetSpriteByGem(m_pGem);
			pSprite->m_Pos = m_pEditor->GetMousePos();
			pSprite->RenderRotated();
			FontManager::Instance().PrintCentered(m_pEditor->GetMousePos(), "%i",  m_pGem->m_Type);
		}
	};

	// Rotating is changing type
	virtual void	Rotate(int Dir)
	{
		if(m_pGem)
		{
			m_pGem->m_Type++;
			if ( m_pGem->m_Type > GEM_UNIQUE_COUNT)
				m_pGem->m_Type = 1;
		}
	};

	virtual void	PressLMB()
	{
		int x = 0, y = 0;
		math::Vec2 P = m_pEditor->GetMousePos();
		((MATGame*)GetGame())->GetBoardXY(P,x,y);
		if(x >= 0 && y >= 0)
			MATLogicBoard::Instance().SetContentAt(y,x,m_pGem);

		m_pGem = NULL;
		CreateObj();
	};
	
	virtual bool	TryDelete(const math::Vec2& P) 
	{ 
		int x = 0, y = 0;
		((MATGame*)GetGame())->GetBoardXY(P,x,y);
		if(x >= 0 && y >= 0)
		{
			MATLogicBoard::Instance().SetContentAt(y,x,NULL); 
			return true;			
		}
		return false;
	};	

	
	MATGem*		m_pGem;
	
};


MATGameEditor::MATGameEditor(GameBase* pGame) : EditorMain(pGame)
{
	SetHelp("Editor Help [H]:						\n" 
			"(1): Place Tiles						\n"			
			"(2): Place Bombs						\n"			
			"(F9): Save								\n"
			"(F10): Load							\n");
}

void		MATGameEditor::KeyPressed(input::Keyboard::KEY* pKey)
{
	switch (pKey->KeyID)
	{
			
		case KEY_1:
			SetBrush(new MATBrushTile(this)); 				
		break;		

		case KEY_2:
			SetBrush(new MATBrushBomb(this)); 				
		break;	

		default:
			EditorMain::KeyPressed(pKey);
		break;
	}
}



	